package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.domain.BusStatementItem;
import cn.wolfcode.business.domain.StatementItemVO;
import cn.wolfcode.business.mapper.BusStatementItemMapper;
import cn.wolfcode.business.mapper.BusStatementMapper;
import cn.wolfcode.business.service.BusAppointmentService;
import cn.wolfcode.business.service.BusStatementItemService;
import cn.wolfcode.business.service.BusStatementService;
import cn.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.Security;
import java.util.Date;
import java.util.List;

import static cn.wolfcode.business.domain.BusStatement.STATUS_CONSUME;
import static cn.wolfcode.business.domain.BusStatement.STATUS_PAID;


@Service
@Transactional
public class BusStatementItemImpl implements BusStatementItemService {
    @Autowired
    BusStatementItemMapper busStatementItemMapper;
    @Autowired
    BusStatementService busStatementService;
    @Autowired
    BusAppointmentService busAppointmentService;

    @Transactional
    @Override
    public Integer save(StatementItemVO statementItemVO) {
        //1.参数合理化校验
        if (statementItemVO.getDiscountPrice() == null || statementItemVO.getBusStatementItems().isEmpty())
            throw new RuntimeException("非法参数！！");
        //2.通过集合中第一个元素获取到结算单的id
        Long statementId = statementItemVO.getBusStatementItems().get(0).getStatementId();
        //2.根据结算单id获取到结算单的对象
        BigDecimal discountPrice = statementItemVO.getDiscountPrice();
        BusStatement statement = busStatementService.getStatement(statementId);
        //3.根据结算单对象获取结算单的状态，只有状态是消费中才可以更改结算单
        if (!STATUS_CONSUME.equals(statement.getStatus())) {
            throw new RuntimeException("只有消费中的结算单才能进行修改操作！");
        }
        //4.获取到结算单中的相关信息然后对他的相关值进行修改
        //收款时间：pay_time  payee_id：收款人id 消费总金额：total_amount
        // total_quantity 服务项数量 discount_amount：折扣金额
        // 4.1遍历集合获取到 每件商品的单价生成他们的数量 并且 累加起来  同时计算出服务项数量
        BigDecimal totalAmount = new BigDecimal(BigInteger.ZERO);
        BigDecimal totalQuantity = new BigDecimal(BigInteger.ZERO);
        for (BusStatementItem busStatementItem : statementItemVO.getBusStatementItems()) {
            totalAmount = totalAmount.add(busStatementItem.getItemPrice().multiply(busStatementItem.getItemQuantity()));
            totalQuantity = totalQuantity.add(busStatementItem.getItemQuantity());
        }
        //4.1对价格进行一个合理性验证：即总金额>=优惠价格>=0
        if (totalAmount.compareTo(discountPrice) == -1 || discountPrice.compareTo(BigDecimal.ZERO) == -1)
            throw new RuntimeException("总金额必须大于等于优惠价格且价格都必须大于等于0！");
        //4**当用户需要修改结算单明细数据时需要删除结算单明细表中的原先已存在的明细数据
        Long itemId = statementItemVO.getBusStatementItems().get(0).getItemId();
        //4.2修改将需要修改的参数通过方法传递过去
        Integer modify = busStatementService.Modify(statementId, totalAmount, totalQuantity, discountPrice);
        //4**先根据结算单id在结算单明细表中删除所有的数据后再执行插入
        busStatementItemMapper.deleteByStatementId(statementId);
        //4.3执行插入方法，将结算单明细的数据插入到结算单明
        return busStatementItemMapper.insert(statementItemVO.getBusStatementItems());
    }

    @Override
    public List<BusStatementItem> getStatementItem(Long id) {
        List<BusStatementItem> statementItem = busStatementItemMapper.getStatementItem(id);
        return statementItem;
    }

    /**
     * 完成支付功能，支付的本质上就是将结算单的状态修改为已支付
     */
    @Override
    public Integer payUpdateStates(Long statementId) {
        //支付在逻辑上需要进行那些判断？
        if (statementId == null) {
            throw new RuntimeException("非法参数！!");
        }
        //啥时候能够支付
        //1.在结算单的状态为消费中才能支付，所以需要通过结算单id获取到结算的状态
        BusStatement statement = busStatementService.getStatement(statementId);
        if (!STATUS_CONSUME.equals(busStatementService.getStatement(statementId).getStatus())) {
            throw new RuntimeException("支付状态异常，只有在消费中才能进行支付！");
        }
        //同时补全结算单表确实的属性
        //收款人id
        Long userId = SecurityUtils.getUserId();
        // 点击支付后,同时需要维护预约单中的状态,如果他是预约用户的即他的预约id！=null
        if (statement.getAppointmentId()!= null) {
            busAppointmentService.payUpdateStates(statement.getAppointmentId());
        }
        //更新结算单表,根据id修改，状态，收款人id，时间
        return busStatementService.payUpdateStatement(statementId, userId, new Date(), STATUS_PAID);
    }

}